2

Git笔记

参考文档

起步

什么是Git

分布式的版本控制系统

初次运行Git前的配置

设置用户名

$ git config --global user.name "John Doe"
设置邮件地址
$ git config --global user.email johndoe@example.com
查看配置信息
$ git config --list
检查某一项配置
$ git config <key>
获取git命令的使用手册
$ git help <verb>

Git基础

获取Git仓库
  1. 初始化仓库
    $ git init
  2. 克隆现有的仓库
  • git clone <URL> 获取默认分支代码
    $ git clone https://github.com/libgit2/libgit2
  • git clone <URL> <新名字> 拉取仓库时自定义本地仓库文件名
    $ git clone https://github.com/libgit2/libgit2 mylibgit
  • git clone -b <分支名> <代码地址> 直接拉取特定分之的代码
    $ git clone -b dev http://192.168.102.9/jas-paas/cloudlink-front-framework.git
  • git clone -b <标签名> <代码地址> 直接拉取特定标签(tag)的代码
    $ git clone -b V2.2 http://192.168.102.9/jas-paas/cloudlink-front-framework.git
.gitignore 忽略文件,不纳入GIT版本控制
  1. 所有空行或者以 # 开头的行都会被 Git 忽略。
  2. 可以使用标准的 glob 模式匹配。
  3. 匹配模式可以以(/)开头防止递归。
  4. 匹配模式可以以(/)结尾指定目录。
  5. 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
# 忽略所有后缀为 .a 的文件
*.a
# 但是要跟踪lib.a,即使你上面忽略了 .a文件
!lib.a
# 仅忽略当前目录的TODO文件夹, 不是subdir/TODO 
/TODO
# 忽略build /目录中的所有文件
build/
# 忽略doc / notes.txt,而不是doc / server / arch.txt
doc/*.txt
# 忽略doc 目录中的所有.pdf文件
doc/**/*.pdf
文件状态介绍
  • Changes to be committed 已暂存
  • Changes not staged for commit 已修改
  • Untracked files 未跟踪
检查当前文件状态
$ git status
$ git status -s                // 或者 git status -short , 紧凑格式输出
跟踪新文件(并把已跟踪文件放到暂存区)
$ git add src/test.txt    // 指定单个文件添加
$ git add src/*           // 指定src目录下所有文件都添加
$ git add .               // 全部添加
git checkout -- <file> 撤销对文件的修改(该文件任何修改都会消失!)
$ git checkout -- CONTRIBUTING.md
git reset HEAD -- <file> 取消暂存的文件(将文件从暂存区回退到工作区)
$ git reset HEAD CONTRIBUTING.md
git diff
  • 查看尚未暂存的文件修改记录 (Changes not staged for commit 下面的文件)

    git diff 输出结果介绍

    $ git diff        // 查看所有已暂存文件的修改记录
    $ git diff t.txt  // 只查看1.txt文件 已暂存的修改记录
  • git diff --staged 查看已暂存文件修改记录

    $ git diff --staged        // 查看所有已暂存文件的修改记录
    $ git diff --staged t.txt  // 只查看1.txt文件 已暂存的修改记录
  • 其他用法

    $ git diff --stat         // 查看简单的diff结果,只查看修改的文件名、修改了多少内容
    $ git diff HEAD           // 查看所有修改记录(已暂存、已修改)显示(Working tree)和HEAD的差别
    $ git diff topic master   // 直接将两个分支上最新的提交做diff
    $ git diff HEAD^ HEAD     // 比较上次提交commit和上上次提交
    $ git diff SHA1 SHA2      // 比较两个历史版本之间的差异
git commit 提交更新(暂存区提交到仓库区)
$ git commit                                           // 会启动文本编辑器以便输入本次提交的说明
$ git commit -m "Story 182: Fix benchmarks for speed"  // 将提交信息与命令放在同一行
$ git commit -a -m 'added new benchmarks'              // 跳过使用暂存区域
$ git commit --amend      // 如果漏掉了文件没有添加,或者提交信息写错了,可以尝试重新添加
git log 查看提交历史,方便版本回滚
$ git log 1.txt            // 查看 1.txt文件的历史修改记录
$ git log -n               // 只查看前n次修改记录,例如查看前2次的记录:git log -2
$ git log -p               // 按补丁格式显示每个更新之间的差异
$ git log --stat           // 显示每次更新统计信息(修改的文件名,每个文件添加的多少、删除了多少数字)
$ git log --shortstat      // 只显示 --stat 中最后的行数修改添加移除统计。
$ git log --name-status    // 显示新增、修改、删除的文件清单。
$ git log --name-only      // 只显示修改的文件名,没有其他信息
$ git log --abbrev-commit  // 仅显示 SHA-1 的前几个字符,而非所有的 40 个字符。
$ git log --relative-date  // 使用较短的相对时间显示(比如,“2 weeks ago”)。
$ git log --graph          // 显示 分支合并历史。   
$ git log --pretty=oneline // 用一行显示信息
git reset (--mixed) HEAD~1

撤销commit和add,工作区内容不变

回退一个版本,且会将暂存区的内容和本地已提交的内容全部恢复到未暂存的状态,不影响原来本地文件(未提交的也
不受影响)

git reset --soft HEAD~1

仅撤销commit,暂存区、工作区内容不变

回退一个版本,不清空暂存区,将已提交的内容恢复到暂存区,不影响原来本地的文件(未提交的也不受影响)

git reset --hard HEAD~1 (危险操作,数据会丢失)

想恢复到某个版本库的代码(暂存区,工作区均变化)

回退一个版本,清空暂存区,将已提交的内容的版本恢复到本地,本地的文件也将被恢复的版本替换

远程仓库的使用

查看远程仓库
$ git remote      // 指定的远程服务器的简写,origin - 这是 Git 给你克隆的仓库服务器的默认名字
origin
$ git remote -v   // 读写远程仓库使用的 Git 保存的简写与其对应的 URL
origin    https://github.com/schacon/ticgit (fetch)
origin    https://github.com/schacon/ticgit (push)
git remote add <shortname> <url> 添加远程仓库
$ git remote add pb https://github.com/paulboone/ticgit
$ git remote -v
origin    https://github.com/schacon/ticgit (fetch)
origin    https://github.com/schacon/ticgit (push)
pb    https://github.com/paulboone/ticgit (fetch)
pb    https://github.com/paulboone/ticgit (push)
git fetch [remote-name] 从远程仓库中抓取与拉取
git pull <仓库名> <分支名> 有多个远程仓库,拉取指定仓库
$ git pull github master   // 比如远程仓库有origin、github,默认origin,如果拉取github仓库的代码
远程仓库的重命名与移除
$ git remote rename pb paul
$ git remote
origin
paul
$ git remote rm paul
$ git remote
origin

打标签

查看标签
  • git tag 列出所有标签

    $ git tag   
    v0.1
    v1.3
    v1.4
  • 查看符合条件的标签

    $ git tag -l 'v1.*'      // 只查看1.0以上tag
  • 查看一个标签的详细信息

    $ git tag show V1.4
创建标签
  • git tag -a 创建附注标签(annotated)

    附注标签是存储在 Git 数据库中的一个完整对象。 它们是可以被校验的;其中包含打标签者的名字、电子邮件地址、日期时间;还有一个标签信息;并且可以使用 GNU Privacy Guard (GPG)签名与验证。

    $ git tag -a v1.4 -m 'my version 1.4'   // -m 选项指定了一条将会存储在标签中的信息。 如果没有               
    为附注标签指定一条信息,Git 会运行编辑器要求你输入信息。
  • 创建轻量标签(lightweight)

    如果你只是想用一个临时的标签,或者因为某些原因不想要保存那些信息,则可以选择使用轻量标签。轻量标签本质上是将提交校验和存储到一个文件中 - 没有保存任何其他信息。
    创建轻量标签,不需要使用 -a、-s 或 -m 选项,只需要提供标签名字

    $ git tag v1.4-lw
    $ git tag
    v1.4
    v1.4-lw
  • 后期打标签

    如果你在项目版本发布的时候忙忘记打标签,你可以在之后补上标签。
    要在那个提交上打标签,你需要在命令的末尾指定提交的校验和(或部分校验和)

    git tag -a v1.2 9fceb02    
git push origin [tagname]共享标签(把创建的标签推送到服务器上)

默认情况下,git push命令并不会传送标签到远程仓库服务器上。 在创建完标签后你必须显式地推送标签到共享服务器上。

$ git push origin v1.5
$ git push origin --tags      // 把所有不在远程仓库服务器上的标签全部传送到服务器
检出标签: 代码变成标签的样子

在 Git 中你并不能真的检出一个标签,因为它们并不能像分支一样来回移动。
如果你想要工作目录与仓库中特定的标签版本完全一样,
可以使用git checkout -b [branchname] [tagname]在特定的标签上创建一个新分支

$ git checkout -b version2 v2.0.0
Switched to a new branch 'version2'
删除标签
$ git tag -d v1.0                       // 删除本地标签
$ git push origin :refs/tags/v0.1       // 删除服务器标签

如果服务器的标签删除后,本地的也需要自己删除。

Git分支

分支介绍

Git 的分支,其实本质上仅仅是指向提交对象的可变指针。 Git 的默认分支名字是 master。
在多次提交操作之后,你其实已经有一个指向最后那个提交对象的 master 分支。 它会在每次的提交操作中自动向前移动。

分支作用:

  1. 开发多个项目任务,比如说我有两个任务都比较紧急,任务1需要两天完成,任务2需要一天完成,而任务1是之前就已经开始进行的,任务二是中间加的新任务,所以需要第一天就完成任务2.
  2. master分支始终要保证可发布的状态,用dev分支和bug分支进行开发和错误调试,这样能够保证主干代码的干净、可发布。
  3. 自己开发测试或者修复BUG等等,可以避免代码的丢失。

本地分支的创建、切换、删除

git branch 创建分支
$ git branch testing        // 创建一个 testing 分支
git checkout 切换分支
$ git checkout testing      // 切换到 testing 分支
git checkout -b 创建并切换
$ git checkout -b testing
Switched to a new branch "testing"
git checkout -b <分支名> <远程仓库名>/<分支名> 创建分支并拉取远程分支代码(已经拉取了代码,还需要拉取其他分支的代码)
$ git checkout -b develop origin/develop    // 提取远程新分支到本地
git branch -d 删除分支
$ git branch -d testing
Deleted branch testing (was 4baf2a3).

远程分支的新建与删除

git branch -a 查看远程仓库分支
git push origin 新建远程仓库的分支
$ git br -a
  testing
* master
  remotes/origin/master

$ git push origin testing      // 将本地 testing 分支作为远程 testing 分支
Total 0 (delta 0), reused 0 (delta 0)
To http://192.168.132.00/user/test.git
 * [new branch]      testing -> testing
git push origin --delete 删除远程仓库的无用分支
git push origin --delete testing
To http://192.168.132.00/user/test.git
 - [deleted]         testing

git push 将本地的更新推送到远程仓库

$ git push origin master     // 把更新上传到 origin 服务器的 master 分支上
$ git push                   // 上传本地所有分支代码到远程对应的分支上
git pull origin <分支> 取回远程仓库的变化,并自动与本地分支合并
git fetch origin <分支> 从远程获取最新变化到本地,但不会自动merge

分支合并 git merge

例如,现在有2个分支(master, ningning),master分支的代码要合并到ningning,2个分支代码都已经commit过了。如果没有commit,需要先commit,否则不能合并代码。

git merge <分支名> 合并命令
// 切换到需要添加新功能的分支上
$ git checkout ningning
// 把 master分支上的代码合并到ningning分支上
$ git merge master
直接合并成功的提示
$ git merge master 
Updating f42c576..3a0874c
Fast-forward
 index.html | 2 ++
 1 file changed, 2 insertions(+)   

// 或者下面的输出信息
Merge made by the 'recursive' strategy.
index.html |    1 +
1 file changed, 1 insertion(+)

Git 将合并的结果做了一个新的快照并且自动创建一个新的提交指向它。

遇到冲突时的分支合并
  • 错误信息类似于

    Auto-merging index.html
    CONFLICT (content): Merge conflict in index.html
    Automatic merge failed; fix conflicts and then commit the result.

    Auto-merging是指已经自动合并的文件

    CONFLICT (content)是指有冲突的文件,需要解决冲突的文件。

  • 打开有冲突的文件,冲突部分代码类似于下面:

    <<<<<<< HEAD:ningning
    <div id="footer">contact : email.support@github.com</div>
    =======
    <div id="footer">
     please contact us at support@github.com
    </div>
    >>>>>>> master  

    <<<<< ======= 中的是 ningning分支的代码。
    ======= >>>>>> 中的是 master分支的代码。
    经过对比后删除冲突部分的代码, 并把 <<< ==== >>>> 所在行全部删除。
    保存后,使用git add添加修改的文件。
    使用git commit命令来完成合并提交:

git checkout --ours/--theirs 放弃其中一个分支的冲突代码

如果想放弃一个分支文件的冲突代码,只保留一个分支的代码,可使用如下命令。

假如:冲突文件名为 1.txt,要放弃master分支的修改,可使用如下命令:

$ git checkout --ours 1.txt

放弃ningning分支冲突代码,可使用如下命令:

$ git checkout --theirs 1.txt 
git reset --hard HEAD 取消合并
  • 如果冲突代码太多了,解决冲突代码过程中产生了混乱,想要重新合并,可使用下面命令取消这次合并:

    git reset --hard HEAD
    HEAD is now at 9e791f3 提交信息
  • 如果合并的代码产生了错误,或者合并有问题,但是已经commit了,但是还没有把合并提交到远程仓库,则可以使用如下命令取消这次合并:

    $ git reset --hard HEAD^ 

Snoopy
19 声望2 粉丝